home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / langs / pcl-src.zoo / march-92-notes.txt < prev    next >
Encoding:
Text File  |  1992-04-19  |  14.0 KB  |  312 lines

  1. These notes correspond to the "March 92 PCL (beta1)" version of PCL.
  2.  
  3.   This version of PCL is much closer than previous versions of PCL
  4. to the metaobject protocol specified in "The Art of the Metaobject Protocol", 
  5. chapters 5 and 6, by Gregor Kiczales, Jim des Riveres, and Daniel G. Bobrow.
  6.  
  7.  
  8. [Please read the file may-day-notes.text also.  Most of that file still applies.]
  9.  
  10. Support for structures
  11.   You can use structure-class as a metaclass to create new classes.
  12.   Classes created this way create and evaluate defstruct forms which
  13.   have generated symbols for the structure accessors and constructor.
  14.   The generated symbols are used by the primary slot-value-using-class
  15.   methods and by the primary allocate-instance method for structures.
  16.   Defmethod optimizes usages of slot-value (when no user-defined 
  17.   slot-value-using-class methods exist) into direct calls of the
  18.   generated symbol accessor, which the compiler can then optimize further.
  19.   Even when there are user-defined methods on slot-value-using-class,
  20.   PCL does a variety of optimizations.
  21.   
  22.   If your implementation's version of the *-low.lisp file
  23.   contains definitions of certain structure functions (see the end of
  24.   low.lisp, cmu-low.lisp, lucid-low.lisp, and kcl-low.lisp), then
  25.   structure classes are supported for all defstructs.  In this case,
  26.   structure classes are created automatically, when necessary.
  27.  
  28. New Classes:
  29. structure-class
  30. structure-object
  31. slot-class
  32. slot-object
  33. structure-direct-slot-definition
  34. structure-effective-slot-definition
  35.  
  36. Improvements to slot-access
  37.   Optimization for slot-value outsize of defmethod
  38.   Optimization for slot-value inside of defmethod, but not of a specialized parameter.
  39.   Optimizations that work even when there are :around methods
  40.   on slot-value-using-class.
  41.  
  42. New types: 
  43.    `(class ,class-object)
  44.    `(class-eq ,class-object)
  45.  
  46. New specializer class: class-eq-specializer
  47.   Every class has a class-eq specializer which represents all
  48.   the direct instances of that class.
  49.   This is useful in *subtypep.  For example, here is the way 
  50.   generic-function initialization checks that the method-class is valid:
  51.    (and (classp method-class)
  52.     (*subtypep (class-eq-specializer method-class)
  53.            (find-class 'standard-method)))
  54.   If you want to define methods having class-eq specializers,
  55.   see "Initialization of method metaobjects".  The default behavior of PCL
  56.   is to disallow this.
  57.  
  58. compute-applicable-methods-using-types
  59.  
  60. caching improvements
  61.  
  62. no magic-generic-functions list
  63.   This simplifies some things, but complicates some other things.
  64.   I wanted to support user-defined classes which are their own metaclass.
  65.   You can now do:
  66. (defclass y (standard-class) ())
  67. (defmethod validate-superclass ((c y) (sc standard-class)) t)
  68. (defclass y (standard-class) () (:metaclass y))
  69.  
  70. method-function changes (see the comments for make-method-lambda, below)
  71.  
  72. final dfuns
  73.  
  74. -------------------------
  75.  
  76. gfs which obey AMOP ch 6
  77.   add-dependent
  78.   add-direct-method
  79.   add-direct-subclass
  80.   add-method
  81.   allocate-instance
  82.   compute-class-precedence-list
  83.   compute-default-initargs
  84.   compute-effective-slot-definition
  85. [Note: compute-effective-slot-definition relys on 
  86.  compute-effective-slot-definition-initargs and effective-slot-definition-class.
  87.  compute-effective-slot-definition-initargs is quite useful, but is not in
  88.  AMOP ch 6.]
  89.   compute-slots
  90.   direct-slot-definition-class
  91.   effective-slot-definition-class
  92.   ensure-class
  93.   ensure-class-using-class
  94.   ensure-generic-function
  95.   ensure-generic-function-using-class
  96.   eql-specializer-object
  97.   extract-lambda-list
  98.   extract-specializer-names
  99.   finalize-inheritance
  100.   find-method-combination
  101.   funcallable-standard-instance-access
  102.   {generic-function-method-class, generic-function-method-combination,
  103.    generic-function-lambda-list, generic-function-methods, generic-function-name}
  104.   intern-eql-specializer
  105.   make-instance
  106.   map-dependents
  107.   {method-function, method-generic-function, method-lambda-list,
  108.    method-specializers, method-qualifiers}
  109.   {class-default-initargs, class-direct-default-initargs, class-direct-slots,
  110.    class-direct-subclasses, class-direct-superclasses, class-finalized-p,
  111.    class-name, class-precedence-list, class-prototype, class-slots}
  112.   {slot-definition-allocation, slot-definition-initargs, slot-definition-initform,
  113.    slot-definition-initfunction, slot-definition-name, slot-definition-type}
  114.   {slot-definition-readers, slot-definition-writers}
  115.   {slot-definition-location}
  116.   remove-dependent
  117.   remove-direct-method
  118.   remove-direct-subclass
  119.   remove-method
  120.   set-funcallable-instance-function
  121.   (setf slot-value-using-class)
  122.   slot-boundp-using-class
  123.   slot-makunbound-using-class
  124.   specializer-direct-generic-functions
  125.   specializer-direct-methods
  126.   standard-instance-access
  127.   update-dependent
  128.  
  129. gfs which DO NOT obey AMOP ch 6
  130.  
  131. accessor-method-slot-definition
  132.   Not yet defined.  Use accessor-method-slot-name and method-specializers
  133.   to get the direct-slot-definition.
  134.  
  135. compute-applicable-methods
  136. compute-applicable-methods-using-classes
  137.   Handles class-eq specializers without signalling an error.  
  138.   But see "Initialization of method metaobjects", below.
  139.  
  140. compute-discriminating-function
  141.   [the resulting function works differently different because 
  142.    compute-effective-method is different, and because make-method-lambda 
  143.    does not exist.]
  144.  
  145. compute-effective-method
  146.   Returns only one value.  The utility of bringing this into conformance with
  147.   AMOP ch 6 is limited by the lack of make-method-lambda.
  148.  
  149. generic-function-argument-precedence-order
  150.   Not yet defined.  Can get this information from the arg-info structure.
  151.  
  152. generic-function-declarations
  153.   Not yet defined.
  154.  
  155. make-method-lambda
  156.   Does not exist.  This will be hard to add in a way that is compatible with
  157.   AMOP ch 6.
  158.   1. In March 92 PCL, there are two kinds of method-functions.  The first kind
  159.      is what method-function returns (which has no special restrinctions on its use).
  160.      The second kind is returned by method-function-for-caching, which is used
  161.      when the wrappers of the required arguments are known.  Each call to
  162.      method-function-for-caching might return a new function.  Both kinds of
  163.      method functions can be closures.  March 92 PCL currently uses this scheme
  164.      to do the pv-lookup ahead of time, thereby eliminating pv caching.
  165.      (pv-lookup means the lookup of the permutation vectors which are used for
  166.      fast instance varaible access.)   Method function closures can also be used
  167.      in the optimization of calls to generic-functions, but this has not yet been
  168.      implemented.
  169.   2. Since method-functions can be closures, we would need an extra step between
  170.      compiling (or coercing) the method-lambda into a function, before it can be 
  171.      applied to arguments with apply or funcall.     
  172.  
  173. reader-method-class
  174.   Not yet defined.  Some bootstrapping considerations are involved, 
  175.   but adding this will not be very hard.
  176.  
  177. (setf class-name)
  178.   Currently just a writer method.  Does not call reinitialize-instance or
  179.   (setf find-class).
  180.  
  181. (setf generic-function-name)
  182.   Currently just a writer method.  Does not call reinitialize-instance.
  183.  
  184. writer-method-class
  185.   Not yet defined.  Some bootstrapping considerations are involved, 
  186.   but adding this will not be very hard.
  187.  
  188. ---------------------------
  189.  
  190. Initialization of method metaobjects
  191.   The following methods are defined:
  192.     legal-qualifiers-p (method standard-method) qualifiers
  193.     legal-lambda-list-p (method standard-method) lambda-list
  194.     legal-specializers-p (method standard-method) specializers
  195.     legal-method-function-p (method standard-method) function
  196.     legal-documentation-p (method standard-method) documentation
  197.  
  198.     legal-specializer-p (method standard-method) specializer
  199.  
  200.   You can override them if you want.
  201.   The method for legal-specializers-p calls legal-specializer-p
  202.   on each specializer.
  203.   The method for legal-specializer-p allows any kind of specializer
  204.   when the variable *allow-experimental-specializers-p* is t
  205.   (this variable is initially nil).
  206.  
  207. ---------------------------
  208. Optimizations on slot-value
  209.   Outside of a defmethod when define-compiler-macro is not implemented
  210.   or the slot-name is not constant, or
  211.   Inside a defmethod when the slot-name is not a constant:
  212. (1)   no optimization of slot-value, slot-value-using-class is called.
  213.       slot-value-using-class has a special dfun, though, which calls
  214.       the slot's slot-definition-reader-function.  This function is
  215.       a result of get-accessor-method-function.
  216.   Outside of a defmethod when define-compiler-macro is implemented and
  217.   the slot-name is a constant, or
  218.   Inside a defmethod when the slot-name is a constant but the object is 
  219.   not either (the value of a parameter specialized to a subclass of structure-object
  220.   for which no user-defined slot-value-using-class methods apply at defmethod time), 
  221.   or (the value of a parameter specialized to a subclass of standard-object).
  222. (2)   PCL arranges to call an automatically created generic function
  223.       which has one method: a reader method defined on class slot-object.
  224.   Inside a defmethod when the slot-name is a constant and the object 
  225.   is (the value of a parameter specialized to a subclass of structure-object
  226.   for which no user-defined slot-value-using-class methods apply).
  227. (3)   The slot-value form is converted to a call of the structure slot's 
  228.       accessor function, which the compiler can then optimize further.
  229.   Inside a defmethod when the slot-name is a constant and the object 
  230.   is (the value of a parameter specialized to a subclass of standard-object).
  231. (4)   The access requires two arefs, a call to (typep x 'fixnum), and a call to eq,
  232.       in the best case.  If user defined slot-value-using-class methods apply
  233.       at slot-value execution time, or the slot is unbound, the unoptimized 
  234.       slot-value function (1) is called.  This was in May Day PCL; what is new here
  235.       is that the PV (permutation vector) is looked up at defmethod load time
  236.       rather than at run time, if the effective method is cached.
  237.  
  238. Generic functions containing only accessor methods for which no user-defined
  239. methods on slot-value-using-class apply and which involve only standard-classes:
  240.       A special dfun is called: one-class, two-class, one-index, or n-n.
  241.       These were all in May Day PCL.
  242. Generic functions excluded by the above, which contain accessor methods:
  243.       In place of each accessor method's method-function, a function returned by
  244.       get-accessor-method-function is used.
  245.  
  246. get-accessor-method-function (gf type class slotd) ; type is reader, writer, or boundp.
  247.   If there is only one applicable method,
  248.       (This method will be the system supplied one)
  249.       the function that is returned is optimized for the current state of the
  250.       class.  When the class changes, it must be recomputed.
  251.   otherwise,
  252.       a secondary dispatch function for slot-value-using-class is computed
  253.       (using what is known about the types of the arguments) and converted 
  254.       into an accessor function.
  255.  
  256. get-secondary-dispatch-function (gf methods types &optional method-alist wrappers)
  257.   The types argument describes what is known about the types of the arguments.
  258.   Method-alist is used (when supplied) to do things like replace the
  259.   standard slot-value-using-class method function with a function optimized
  260.   for what is known about the arguments.
  261.   Wrappers (when supplied) means that the resulting function is guaranteed to
  262.   be called only whith those wrappers.  Make-effective-method-function calls
  263.   the generic-function method-function-for-caching with method-alist and
  264.   wrappers to get a optimized method function.  (PV lookup is done at the time
  265.   method-function-for-caching is called).
  266.  
  267. compute-applicable-methods:  Here I tried to stick with the MOP.
  268.   The function cache-miss-values looks at the second value of the result of 
  269.   compute-applicable-methods-using-classes.  If this value is null, we aren't 
  270.   supposed to cache the result of camuc.  So we don't.  Instead we cache a 
  271.   result of (default-secondary-dispatch-function gf), which in turn calls 
  272.   compute-applicable-methods each time it is called.
  273. ---------------------------
  274.  
  275. To do:
  276.  
  277. 1.   Make the metaobject protocol function symbols be the external symbols
  278.   of a package, so they can be used easily.
  279.  
  280. Problem: sometimes there is no need to call a gf's dfun: the emf that is invoked
  281.          can be cached in the caller's method closure.
  282.          make-instance is slow.
  283. 2.  In expand-defmethod-internal, optimize calls to generic-functions.
  284.   Add the support for this optimization.
  285.  
  286. 3.   Make sure that use-dispatch-dfun-p is doing the right thing.
  287.  
  288. 4.   [When CMUCL improves its setf handling, remove the comment in
  289.    the file macros.lisp beginning the line ";#+cmu (pushnew :setf *features*)"]
  290.  
  291.  
  292.  
  293. --------------
  294. 1) Generalize expand-defmethod-internal so that it can be used for non-defmethod
  295. code.  Maybe by (a) having a parameter that says whether it is being called by 
  296. defmethod, and (b) using the techniques used by the series package (shadowing 
  297. defun and some others, making the shadowed definitions call e-d-i, making it 
  298. easy for people to do the relevant package modifications)
  299.  
  300. 2) Extending generic-functions by allowing the user at defgeneric time to supply
  301. the name of a function which will be supplied (by the system) with a definition
  302. which will return equivalent results to those returned by the generic function,
  303. but which will (in some cases) have less checking than the generic function.
  304. One-class, two-class, and one-index gf dfuns will map to a result of 
  305. get-optimized-std-accessor-method-function, checking gf dfuns will map to their
  306. function, and any other dfun will remain the same.
  307.  
  308. 3) Extending expand-defmethod-internal to optimize calls to generic-functions.
  309. There are a variety of possibilities that need to be considered; one of them
  310. will be to arrange to call the optimized functions produced by (2) when it
  311. is known to be safe.  
  312.